home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
p063b9s.zip
/
UNIT
/
EVENT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-06-25
|
17KB
|
499 lines
UNIT Event;
{╔══════════════════════════════════════════════════════════════════════════╗}
{║ Event handler & supporting routines Last changed: 25.06.96 SA ║}
{║ ║}
{║ (C) Copyright 1989-96 by ║}
{║ Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager ║}
{║ ║}
{║ This source may not be given to anybody, without the written permission ║}
{║ from The Portal Team. ║}
{╚══════════════════════════════════════════════════════════════════════════╝}
{$I POPDEFS.INC}
INTERFACE
USES Use32;
FUNCTION CalculateNextTime: LongInt;
PROCEDURE ChangeEvent(TestChange: Boolean);
PROCEDURE CalculateEventTimes(JustTest: Boolean);
CONST
TimeToNextEvent : LongInt = 0;
TimeToNextForcedEvent : LongInt = 0;
TimeToNoMoreRequest : LongInt = 0;
{ NextEventNumber : LongInt = 0;}
IMPLEMENTATION
USES Dos, OpDate, OpString, OpRoot, ApTimer,
Com, StrUtil, Util, Globals, Display, FileUtil, LogFile, NetFile,
List, PoPTypes, Send2Utl, OutUtil, OutInfo, MailUtil, Modem,
MailScan, OproUtil;
CONST
NextEventTimer : EventTimer = (StartTics: 0; ExpireTics: 0);
FUNCTION CalculateNextTime: LongInt;
VAR
Tmp : POutList;
NumNodes : Word;
CalcTime : LongInt;
BEGIN
WITH CurrentEvent DO
IF (Data.Event>0) AND (CallTime<>0) THEN
CalcTime:=CallTime+Random(callwidth)
ELSE
CalcTime:=Cfg.CallTime+Random(cfg.callwidth);
NumNodes:=0;
Tmp:=POutList(OutList^.Head);
WHILE Tmp<>NIL DO
BEGIN
IF Tmp^.Known AND SendableData(Tmp) THEN Inc(NumNodes);
Tmp:=POutList(OutList^.Next(Tmp));
END;
IF NumNodes=0 THEN NumNodes:=1;
CalculateNextTime:=CalcTime DIV NumNodes;
END;
FUNCTION GetDayMask(CONST Day: Byte) : Byte;
BEGIN
CASE Day OF
0 : getdaymask:=128+64;
1 : getdaymask:=128+1;
2 : getdaymask:=128+2;
3 : getdaymask:=128+4;
4 : getdaymask:=128+8;
5 : getdaymask:=128+16;
6 : getdaymask:=128+32;
END;
END;
FUNCTION DaysTillRun(CONST Event: TEvent): LongInt;
VAR
Flag:BOOLEAN;
DatoAar, DatoMaaned, DatoDag, DatoDofW,
Nd,DDay,DMonth,DYear,SDay,SMonth,SYear,EDay:Word;
d : LongInt;
BEGIN
GetDate(DatoAar,DatoMaaned,DatoDag,DatoDofW);
WITH Event DO
BEGIN
IF Event.Active>128 THEN
BEGIN
d:=0;
IF NOT ((GetDayMask(DatoDofW) AND Event.Active>128) AND
((Event.Start+1>Data.LastEventStart) OR (Data.LastEventDate<>Today)) AND
((Day=0) OR (Day=DatoDag)) AND
((Month=0) OR (Month=DatoMaaned))) THEN
BEGIN
EDay:=DatoDofw;
DDay:=DatoDag; DMonth:=DatoMaaned; DYear:=DatoAar;
SDay:=DatoDag; SMonth:=DatoMaaned; SYear:=DatoAar;
Nd:=DaysInMonth(DMonth,DYear);
REPEAT
INC(DDay);
IF DDay>Nd THEN
BEGIN
DDay:=1;
INC(DMonth);
IF DMonth>12 THEN
BEGIN
DMonth:=1;
INC(DYear);
END;
Nd:=DaysInMonth(DMonth,DYear);
END;
INC(EDay);
IF EDay>6 THEN EDay:=0;
INC(d);
IF ((Day=0) OR (DDay=Day)) THEN Flag:=TRUE ELSE Flag:=False;
IF Flag AND (Month<>0) AND (DMonth<>Month) THEN Flag:=False;
IF Flag AND (Active AND GetDayMask(EDay)<=128) THEN Flag:=False;
UNTIL Flag;
END;
END ELSE
d:=7*366;
END;
DaysTillRun:=d;
END;
PROCEDURE CalculateEventTimes(JustTest: Boolean);
VAR
x : LongInt;
EventFile : TNetFile;
TmpEvent : TEvent;
BEGIN
TimeToNoMoreRequest:=366*SecondsInDay;
TimeToNextForcedEvent:=366*SecondsInDay;
TimeToNextEvent:=SecondsInDay;
IF EventFile.Open(StartPath+PoPEventFileName, SizeOf(TEvent),False)THEN
BEGIN
WHILE NOT EventFile.EOF DO
BEGIN
EventFile.Read(TmpEvent,NoKeep,Wait);
IF (TmpEvent.TaskNumber=0) OR (TmpEvent.TaskNumber=Cfg.TaskNumber) THEN
BEGIN
x:=(DaysTillRun(TmpEvent)*SecondsInDay)+TmpEvent.Start-CurrentTime;
IF x>=0 THEN
BEGIN
IF x<TimeToNextEvent THEN TimeToNextEvent:=x;
IF (TmpEvent.Typ AND etForced<>0) AND
(x<TimeToNextForcedEvent) THEN TimeToNextForcedEvent:=x;
IF (((TmpEvent.Typ AND etForced)<>0) OR
((TmpEvent.Typ AND etRequests)=0)) AND
(x<TimeToNoMoreRequest) THEN TimeToNoMoreRequest:=x;
END;
END;
END;
EventFile.Close;
END;
{ Debug info, do *NOT* remove
FastWrite('NE='+TimeToTimeString('hh:mm',TimeToNextEvent)+
' NR='+TimeToTimeString('hh:mm',TimeToNoMoreRequest)+
' NF='+TimeToTimeString('hh:mm',TimeToNextForcedEvent),1,1,7);
}
IF NOT JustTest THEN NewTimerSecs(NextEventTimer, TimeToNextEvent);
END;
PROCEDURE ChangeEvent(TestChange: Boolean);
VAR
TmpEvent : TEvent;
newevent : Byte;
n, n2 : Time;
x : LongInt;
EventFile : TNetFile;
CorrectEvent, DatoAar, DatoMaaned, DatoDag, DatoDofW: Word;
PROCEDURE CheckSchedules;
VAR
f : TNetFile;
Tab:SendToTabType;
Num:Byte;
Schedule : TSchedule;
PROCEDURE ScheduledPoll;
VAR
i:Byte;
ch : Char;
BEGIN
FOR i:=1 TO Num DO
WITH Tab[i] DO
IF NoAll(Tab[i]) THEN
BEGIN
IF Schedule.stat='N' THEN ch:='F' ELSE ch:=Schedule.Stat;
MakeAPoll(Tab[i],ch);
AddLog('!','Creating poll for '+Address2Str(Tab[i]));
END;
END;
PROCEDURE ScheduledChange;
VAR
ch,ch2:Char;
b, i : Byte;
sr:SearchRec;
s,ss:PathStr;
BusyFile : FILE;
Ind, Ud : PBufTextFile;
l:STRING;
x:Word;
BEGIN
IF Schedule.Stat=' ' THEN Schedule.Stat:='H';
FOR i:=1 TO Num DO
BEGIN
s:=HoldFileName(Tab[i],False);
ss:=COPY(s,1,Length(s)-9);
s:=s+'?LO';
FindFirst(s,Archive,sr);
WHILE DOSError=0 DO
BEGIN
ch:=sr.name[10];
IF ch='F' THEN ch:='N';
IF (Length(sr.name)=12) AND (ch<>Schedule.Stat) THEN
BEGIN
IF Schedule.Stat='N' THEN ch2:='F' ELSE ch2:=Schedule.Stat;
IF MarkNodeBusy(BusyFile,Tab[i]) THEN
BEGIN
New(Ud, InitCreate(ForceExtension(s,ch2+'LO'), SOpenWrite, 1024));
IF Ud<>NIL THEN
BEGIN
New(Ind, Init(ss+sr.name, SOpenRead+ShareDenyRW, 1024));
IF Ind<>NIL THEN
BEGIN
WHILE NOT Ind^.EoF AND (Ud^.GetStatus=0) DO
BEGIN
Ind^.ReadLn(l);
Ud^.WriteLn(l);
END;
Dispose(Ind, Done);
DeleteFile(ss+sr.name);
AddLog('!','Changing stat of attaches for '+Address2Str(Tab[i]));
END;
Dispose(Ud, Done);
END;
UnMarkNodeBusy(BusyFile);
END;
END;
FindNext(sr);
END;
FindClose(sr);
END;
FOR i:=1 TO Num DO
BEGIN
s:=HoldFileName(Tab[i],False);
ss:=COPY(s,1,Length(s)-9);
s:=s+'?UT';
FindFirst(s,Archive,sr);
WHILE DOSError=0 DO
BEGIN
ch:=sr.name[10];
IF ch='O' THEN ch:='N';
IF (Length(sr.name)=12) AND (ch<>Schedule.Stat) THEN
BEGIN
IF Schedule.Stat='N' THEN ch2:='O' ELSE ch2:=Schedule.Stat;
New(Ind, Init(ss+sr.name, SOpenRead+ShareDenyRW, 4096));
New(Ud, Init(COPY(s,1,Length(s)-3)+ch2+'UT', SOpenWrite+ShareDenyRW, 4096));
IF Ud<>Nil THEN
BEGIN
Ud^.SetPos(1, PosEnd);
Ind^.SetPos(SizeOf(TPktHeader), PosAbs);
END ELSE
BEGIN
New(Ud, Init(COPY(s,1,Length(s)-3)+ch2+'UT', SCreate, 4096));
END;
WHILE NOT Ind^.EoF DO
BEGIN
Ind^.Read(b, 1);
Ud^.Write(b, 1);
END;
Dispose(Ind, Done);
Dispose(Ud, Done);
DeleteFile(ss+Sr.Name);
AddLog('!','Changing stat of mail packets '+Address2Str(Tab[i]));
END;
FindNext(sr);
END;
FindClose(sr);
END;
END;
PROCEDURE KillScheduledPoll;
VAR
ch:Char;
i,j:Byte;
sr:SearchRec;
s:PathStr;
BEGIN
ExtFlags[3]:='F';
FOR j:=1 TO Num DO
FOR i:=1 TO 5 DO
IF (Schedule.Stat=' ') OR (Schedule.Stat=ExtFlags[i]) THEN
BEGIN
s:=HoldFileName(Tab[j],False)+ExtFlags[i]+'LO';
FindFirst(s,Archive,sr);
IF (DOSError=0) AND (sr.Size=0) THEN
IF DeleteFile(s) THEN
AddLog('!','Killed poll for '+Address2Str(Tab[Num]));
FindClose(sr);
END;
END;
BEGIN
IF f.Open(StartPath+PoPScheduleFileName,SizeOf(TSchedule),False) THEN
BEGIN
WHILE NOT f.EOF DO
BEGIN
f.Read(Schedule,NoKeep,Wait);
IF (Schedule.Number=0) OR (Schedule.Number=CurrentEvent.SchedNumber) THEN
BEGIN
ReadSendTo(Schedule.Adr,Tab,Num);
CASE Schedule.Action OF
0 : ScheduledPoll;
1 : ScheduledChange;
4 : KillScheduledPoll;
END;
END;
END;
f.Close;
END;
END;
FUNCTION FindCorrectEvent: Word;
VAR
ce,x,Min:LongInt;
BEGIN
EventFile.Seek(0);
ce:=0;
Min:=0;
WHILE NOT EventFile.EOF DO
BEGIN
EventFile.Read(TmpEvent,NoKeep,Wait);
IF (TmpEvent.TaskNumber=0) OR (TmpEvent.TaskNumber=Cfg.TaskNumber) THEN
BEGIN
IF (CurrentTime>=TmpEvent.Start) THEN
BEGIN
x:=(DaysTillRun(TmpEvent)*SecondsInDay)+TmpEvent.Start;
IF (x<86400) AND (x>=Min) THEN
BEGIN
Min:=x;
ce:=EventFile.FilePos;
END;
END;
END;
END;
IF ce=0 THEN ce:=Data.Event;
FindCorrectEvent:=ce;
END;
FUNCTION NextEvent:Word;
VAR
x,Min:LongInt;
ne:Word;
BEGIN
EventFile.Seek(0);
ne:=0;
Min:=10*366*SecondsInDay;
WHILE NOT EventFile.EOF DO
BEGIN
EventFile.Read(TmpEvent,NoKeep,Wait);
IF (TmpEvent.TaskNumber=0) OR (TmpEvent.TaskNumber=Cfg.TaskNumber) THEN
BEGIN
x:=(DaysTillRun(TmpEvent)*SecondsInDay)+TmpEvent.Start;
IF (x<=Min) AND
((TmpEvent.Start>Data.LastEventStart) OR (Data.LastEventStart=0)) THEN
BEGIN
Min:=x;
ne:=EventFile.FilePos;
END;
END;
END;
IF ne=0 THEN ne:=Data.Event;
NextEvent:=ne;
END;
BEGIN
GetDate(datoaar,datomaaned,datodag,datodofw);
IF CurrentTime>=MaxTime-10 THEN Delay(1000);
NewEvent:=Data.Event;
IF (TimerExpired(NextEventTimer)) THEN
BEGIN
{AddLog(' ', 'EVENT CHANGE: Time up');}
TestChange:=True;
END;
IF (Data.LastEventDate<>Today) THEN
BEGIN
{AddLog(' ', 'EVENT CHANGE: New day '+DateToDateString('dd.mm.yy', Data.LastEventDate));}
TestChange:=True;
Data.LastEventDate:=Today-1;
Data.LastEventStart:=0;
Data.Event:=0;
END ELSE
IF (Abs(Data.LastEventStart-CurrentEvent.Start)>10) THEN
BEGIN
{AddLog(' ', 'EVENT CHANGE: New event '+TimeToTimeString('hh:mm', Data.LastEventStart)+' '+
TimeToTimeString('hh:mm', CurrentEvent.Start));}
TestChange:=True;
Data.LastEventStart:=0;
IF (Data.Event<>0) THEN
BEGIN
ASM
OR CmdLineFlags, clJump2Event;
END;
Data.Event:=0;
END;
END;
IF (NOT TestChange) AND (Data.Event>0) AND ((CurrentEvent.Typ AND etDynamic)<>0) AND NOT MailToSend THEN
BEGIN
EventFile.Open(StartPath+PoPEventFileName, SizeOf(TEvent), True);
NewEvent:=NextEvent;
EventFile.Close;
END ELSE
BEGIN
IF TestChange THEN
BEGIN
EventFile.Open(StartPath+PoPEventFileName, SizeOf(TEvent), True);
CorrectEvent:=FindCorrectEvent;
IF Data.Event<>CorrectEvent THEN
BEGIN
IF CmdLineFlags AND clJump2Event=0 THEN NewEvent:=NextEvent
ELSE NewEvent:=CorrectEvent;
END ELSE
NewEvent:=Data.Event;
EventFile.Close;
CalculateEventTimes(False);
END;
END;
IF Data.LastRan<>Today THEN
BEGIN
WITH StatRec^.DayStat[0] DO
BEGIN
AddLog(':', 'Totals today : '+Long2Str(callsout)+' calls out ('+Long2Str(callsgood)+ ' good), Cost '+Long2Str(Cost));
AddLog(':', 'Activity : '+Long2Str(bbssessions)+' user calls, and '+Long2Str(mailsessions)+' mail sessions');
AddLog(':', 'Files count : '+Long2Str(filesin)+' files in, and '+Long2Str(filesout)+' files out');
END;
Move(StatRec^ .DayStat[0],StatRec^.DayStat[1],14);
IF StatRec^.Start.D=0 THEN StatRec^.Start.D:=IncDate(Today,-1,0,0);
Inc(StatRec^.Total.CallsOut,StatRec^.DayStat[0].CallsOut);
Inc(StatRec^.Total.CallsGood,StatRec^.DayStat[0].CallsGood);
Inc(StatRec^.Total.Cost,StatRec^.DayStat[0].Cost);
Inc(StatRec^.Total.BBSSessions,StatRec^.DayStat[0].BBSSessions);
Inc(StatRec^.Total.MailSessions,StatRec^.DayStat[0].MailSessions);
Inc(StatRec^.Total.FilesIn,StatRec^.DayStat[0].FilesIn);
Inc(StatRec^.Total.FilesOut,StatRec^.DayStat[0].FilesOut);
FillChar(StatRec^.DayStat[0], 14, 0);
data.lastran:=Today;
IF (Cfg.TaskNumber<=1) AND (DeleteFile(StartPath+PoPDailyReqInfoFileName)) THEN
AddLog(':', 'Deleting Daily Request Info: PORTAL.DRI');
END;
IF CmdLineFlags AND clJump2Event<>0 THEN
CmdLineFlags:=CmdLineFlags XOR clJump2Event;
IF Data.Event<>NewEvent THEN
BEGIN
EventFile.Open(StartPath+PoPEventFileName,SizeOf(TEvent),TRUE);
IF (Data.Event>0) AND ((CurrentEvent.Typ AND etOnceOnly)<>0) THEN
BEGIN
EventFile.GetRec(CurrentEvent,Data.Event-1,Keep,Wait);
CurrentEvent.Active:=CurrentEvent.Active AND 127;
EventFile.PutRec(CurrentEvent,Data.Event-1);
END;
EventFile.GetRec(CurrentEvent,NewEvent-1,NoKeep,Wait);
EventFile.Close;
Data.Event:=NewEvent;
Data.LastEventStart:=CurrentEvent.Start+1;
Data.LastEventDate:=Today;
UpdateStatusWindow;
AddLog(':', 'Starting event #'+Long2Str(NewEvent));
{$IFNDEF NOMAILSCANNER}
IF CurrentEvent.Typ AND etScanMail<>0 THEN RunMailScanner(CurrentEvent.Typ);
{$ENDIF}
IF ((CurrentEvent.Typ AND etClrOut)<>0) AND (Cfg.TaskNumber<2) THEN
BEGIN
IF DeleteFile(StartPath+PoPUndialFileName) THEN AddLog('#','Undialables cleared');
END;
CheckSchedules;
NewTimerSecs(Data.NextTime, CalculateNextTime);
IF (CurrentEvent.Typ AND etPoPList<>0) THEN ListMain;
IF CurrentEvent.InitExit <> 0 THEN
BEGIN
ComPort^.SetDtr(Low);
SpawnWithErrorlevel(CurrentEvent.InitExit, 'Exit at start of event', True);
END;
NewTimer(NextEventTimer, 0);
InitModemForEvent;
GetOutboundInformation;
UpdateOutboundWindow;
END ELSE
IF TestChange AND TimerExpired(NextEventTimer) THEN NewTimerSecs(NextEventTimer, 10);
IF Data.Event=0 THEN
BEGIN
AddLog('!','Portal events configured incorrectly. Please run PORTAL -c to correct');
FinishPortal;
Halt(250);
END;
END;
END.